﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Newtonsoft.Json;

namespace mrp16062010.Simulation
{
    [JsonObject(IsReference = true)]
    class Ortam
    {
        public string Id { get; set; }
        private DateTime baslangicTarihi;

        public DateTime BaslangicTarihi
        {
            get { return baslangicTarihi; }
            set { baslangicTarihi = value;
                SonTarih = BaslangicTarihi; }
        }

        public Kuyruk.IslemTipi KuyrukSiralamaTipi { get; set; }

        private void ZamanArtirici()
        {
            while (true)
            {
                Console.Out.WriteLine("Saat:" + SonTarih.ToString());
                Tetikle(SonTarih);
                SonTarih = SonTarih.AddMinutes(1);
            }
        }
        
        public DateTime SonTarih = new DateTime();
        Thread thZaman;
        public Ortam()
        {
            thZaman = new Thread(new ThreadStart(ZamanArtirici));
        }

        
        private List<Makine> makineList = new List<Makine>();
        public List<Makine> MakineList
        {
            get { return makineList; }
            set { makineList = value; }
        }

        public List<KuyrukOrtalama> Ortalamalar = new List<KuyrukOrtalama>();

        public void MakineEkle(Makine makine)
        {
            makine.SonTarih = this.BaslangicTarihi;
            makineList.Add(makine);
            makine.Girerken += new Makine.GirerkenHandler(makine_Girerken);
            makine.Cikti += new Makine.CiktiHandler(makine_Cikti);
        }

        void makine_Girerken(object o, EventArgs e)
        {
            Makine gonderen = (Makine)o;
        }

        void makine_Cikti(object o, IsParcasi cikan, EventArgs e)
        {
            Makine gonderen = (Makine)o;
            
        }


        

        public void ParcaAta(IsParcasi parca, IsParcasi gonderenParca)
        {
            
            Makine secilenMakine = makineList.Where(x => x.Merkez.Kod == parca.IM.Kod).Single();
            
            parca.SimulasyonBilgisi.Makinesi = secilenMakine;
            /*
            Thread th = new Thread(delegate()
            {
                secilenMakine.Ekle(parca, gonderenParca);
            });
            th.Start();
            th.Name = "TH "+parca.Op.Ad;
            th.Join();
             * */
            
            secilenMakine.Ekle(parca, gonderenParca);
        }

        public List<Siparis> IslenmekteOlanSiparisler = new List<Siparis>();

        public void ParcaAta(List<IsParcasi> parcalar)
        {
            //parçaların sipariş bilgilerini işlenmekte olan listesine at
            var siparisler = parcalar.GroupBy(x => x.SiparisBilgi);
            foreach (var sip in siparisler)
            {
                if (!IslenmekteOlanSiparisler.Contains(sip.Key))
                {
                    IslenmekteOlanSiparisler.Add(sip.Key);
                }
            }

            List<IsParcasi> makbul = new List<IsParcasi>();
            foreach (Makine mak in makineList)
            {
                List<IsParcasi> templ = parcalar.Where(x => x.IM.Kod == mak.Merkez.Kod).OrderBy(x=>x.BasTarihi).ToList();
                foreach (IsParcasi item in templ)
                {
                    item.SimulasyonBilgisi.Makinesi = mak;
                }
                if (templ.Count > 0)
                {
                    makbul.Add(templ.FirstOrDefault());
                    mak.IlkEkleme(templ);
                }
            }
            makbul = makbul.OrderBy(x => x.BasTarihi).ToList();
            makbul = (from x in makbul
                     orderby x.BasTarihi ascending
                     select x).ToList<IsParcasi>();
            /*foreach (IsParcasi item in makbul)
            {
                Thread th = new Thread(new ThreadStart(item.SimulasyonBilgisi.Makinesi.Calistir));
                th.Start();
                
                //item.SimulasyonBilgisi.Makinesi.Calistir();
            }*/
            //thZaman.Start();
        }

        public void Tetikle(DateTime Tarih)
        {
            /*
            Thread[] th = new Thread[makineList.Count()];
            int sayac = 0;
            foreach (Makine item in makineList)
            {
                th[sayac] = new Thread(delegate()
                {
                    item.Tetikle(Tarih);
                });
                th[sayac].Start();
                sayac++;
                //item.Tetikle(Tarih);
            }
            sayac = 0;
            foreach (Makine item in makineList)
            {
                th[sayac].Join();
                sayac++;
            }
            */
            SonTarih = Tarih;
            foreach (Makine item in makineList)
            {
                item.Tetikle(Tarih);
            }

            KuyrukOrtalama kuyOrt = new KuyrukOrtalama();
            kuyOrt.Tarih = Tarih;
            kuyOrt.OrtalamaAdet = KalanAdetOrtalamasi();
            kuyOrt.OrtalamaUzunluk = KalanUzunlukOrtalamasi();
            kuyOrt.WIP = this.WIP();
            Ortalamalar.Add(kuyOrt);
            this.Ortalama = kuyOrt;
        }

        public KuyrukOrtalama Ortalama { get; set; }

        public void TatilAta(List<IsParcasi> tatilList)
        {
            foreach (Makine mak in makineList)
            {
                //List<IsParcasi> templ = tatilList.Where(x => x.TatilIsMerkezi.Kod == mak.Merkez.Kod).ToList();
                if (tatilList.Count > 0)
                {
                    mak.TatilList.AddRange(tatilList);
                }
            }
        }

        public int KalanAdetOrtalamasi()
        {
            int ortalama = 0;
            foreach (Makine item in makineList)
            {
                ortalama += item.MakinedekiParcalarSayisi;
            }
            //ortalama = ortalama;/// makineList.Count;
            return ortalama;
        }

        public TimeSpan KalanUzunlukOrtalamasi()
        {

            TimeSpan ortalama = new TimeSpan();
            foreach (Makine item in makineList)
            {
                ortalama += item.KalanUzunluk;
            }
            if (ortalama!=TimeSpan.Zero)
            {
                
            }
            //ortalama = ortalama;//TimeSpan.FromTicks(ortalama.Ticks / makineList.Count);
            return ortalama;
        }

        public int WIP()
        {
            if (KalanUzunlukOrtalamasi().TotalMinutes==0 )
            {
                
            }
            int toplamKalanIs=0;
            foreach (Siparis siparis in IslenmekteOlanSiparisler)
            {
                toplamKalanIs += Convert.ToInt32(siparis.IsParcalari.Where(x => x.SimulasyonBilgisi.IslemeTarihi.BaslangicTarihi == DateTime.MinValue).Sum(x => x.Uzunluk.TotalMinutes));
            }
            foreach (Makine mak in this.makineList)
            {
                toplamKalanIs += Convert.ToInt32(mak.IslemdekiKalanUzunluk.TotalMinutes);
            }
            return toplamKalanIs;
        }
    }
}
